#!/bin/bash
###############################################################################
#       脚本名称: log_level.sh
#       功能描述: 日志级别管理模块,提供级别定义、比较和颜色管理功能。
#       作者: 林再来
#       日期: 2025-10-14
#       版本: 1.0
#       功能:
#           1、定义标准日志级别(TRACE/DEBUG/INFO/WARN/ERROR/FATAL)
#           2、提供日志级别比较功能
#           3、提供级别颜色映射(ANSI颜色码)
#           4、级别有效性验证
#       依赖(插件/命令):
#           无
###############################################################################

# 防止重复加载
[[ -n "${_LOG_LEVEL_LOADED:-}" ]] && return 0
readonly _LOG_LEVEL_LOADED=1

#-----------------------------------------------------------------------------
# 日志级别常量定义(数值越大级别越高)
#-----------------------------------------------------------------------------
readonly LOG_LEVEL_TRACE=0
readonly LOG_LEVEL_DEBUG=1
readonly LOG_LEVEL_INFO=2
readonly LOG_LEVEL_WARN=3
readonly LOG_LEVEL_ERROR=4
readonly LOG_LEVEL_FATAL=5

# 级别名称数组
readonly -a LOG_LEVEL_NAMES=(
    "TRACE"
    "DEBUG"
    "INFO"
    "WARN"
    "ERROR"
    "FATAL"
)

# 级别名称到数值的映射(关联数组)
declare -gA _LOG_LEVEL_MAP=(
    ["TRACE"]=$LOG_LEVEL_TRACE
    ["DEBUG"]=$LOG_LEVEL_DEBUG
    ["INFO"]=$LOG_LEVEL_INFO
    ["WARN"]=$LOG_LEVEL_WARN
    ["ERROR"]=$LOG_LEVEL_ERROR
    ["FATAL"]=$LOG_LEVEL_FATAL
)

#-----------------------------------------------------------------------------
# ANSI颜色代码定义
#-----------------------------------------------------------------------------
readonly COLOR_RESET="\033[0m"
readonly COLOR_TRACE="\033[0;37m"      # 白色
readonly COLOR_DEBUG="\033[0;36m"      # 青色
readonly COLOR_INFO="\033[0;32m"       # 绿色
readonly COLOR_WARN="\033[0;33m"       # 黄色
readonly COLOR_ERROR="\033[0;31m"      # 红色
readonly COLOR_FATAL="\033[1;31m"      # 粗体红色

# 级别颜色映射
declare -gA _LOG_LEVEL_COLORS=(
    ["TRACE"]="$COLOR_TRACE"
    ["DEBUG"]="$COLOR_DEBUG"
    ["INFO"]="$COLOR_INFO"
    ["WARN"]="$COLOR_WARN"
    ["ERROR"]="$COLOR_ERROR"
    ["FATAL"]="$COLOR_FATAL"
)

#-----------------------------------------------------------------------------
# 函数: 将级别名称转换为数值
# 参数: $1 - 级别名称(TRACE/DEBUG/INFO/WARN/ERROR/FATAL)
# 返回: 输出级别数值,失败返回-1
#-----------------------------------------------------------------------------
function _log_level_to_number() {
    local level_name="${1^^}"  # 转大写
    
    if [[ -z "${_LOG_LEVEL_MAP[$level_name]:-}" ]]; then
        echo "-1"
        return 1
    fi
    
    echo "${_LOG_LEVEL_MAP[$level_name]}"
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 将级别数值转换为名称
# 参数: $1 - 级别数值(0-5)
# 返回: 输出级别名称,失败返回空字符串
#-----------------------------------------------------------------------------
function _log_level_to_name() {
    local level_num="$1"
    
    if [[ ! "$level_num" =~ ^[0-5]$ ]]; then
        echo ""
        return 1
    fi
    
    echo "${LOG_LEVEL_NAMES[$level_num]}"
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 验证级别名称是否有效
# 参数: $1 - 级别名称
# 返回: 0-有效, 1-无效
#-----------------------------------------------------------------------------
function _log_level_is_valid() {
    local level_name="${1^^}"
    [[ -n "${_LOG_LEVEL_MAP[$level_name]:-}" ]]
}

#-----------------------------------------------------------------------------
# 函数: 比较两个日志级别
# 参数: $1 - 级别1(名称或数值), $2 - 级别2(名称或数值)
# 返回: 0-级别1>=级别2, 1-级别1<级别2
# 说明: 用于判断日志是否应该记录
#-----------------------------------------------------------------------------
function _log_level_compare() {
    local level1="$1"
    local level2="$2"
    local num1 num2
    
    # 转换为数值
    if [[ "$level1" =~ ^[0-9]+$ ]]; then
        num1="$level1"
    else
        num1=$(_log_level_to_number "$level1")
        [[ $num1 -eq -1 ]] && return 1
    fi
    
    if [[ "$level2" =~ ^[0-9]+$ ]]; then
        num2="$level2"
    else
        num2=$(_log_level_to_number "$level2")
        [[ $num2 -eq -1 ]] && return 1
    fi
    
    # 比较数值
    [[ $num1 -ge $num2 ]]
}

#-----------------------------------------------------------------------------
# 函数: 获取级别对应的ANSI颜色代码
# 参数: $1 - 级别名称
# 返回: 输出颜色代码,失败返回重置代码
#-----------------------------------------------------------------------------
function _log_level_get_color() {
    local level_name="${1^^}"
    
    if [[ -z "${_LOG_LEVEL_COLORS[$level_name]:-}" ]]; then
        echo "$COLOR_RESET"
        return 1
    fi
    
    echo "${_LOG_LEVEL_COLORS[$level_name]}"
    return 0
}

#-----------------------------------------------------------------------------
# 函数: 判断是否应该记录日志
# 参数: $1 - 当前日志级别, $2 - 全局最小级别
# 返回: 0-应该记录, 1-不应该记录
# 说明: 这是性能优化的关键函数,快速判断避免不必要的处理
#-----------------------------------------------------------------------------
function _log_should_log() {
    local current_level="$1"
    local min_level="${2:-INFO}"
    
    _log_level_compare "$current_level" "$min_level"
}

#-----------------------------------------------------------------------------
# 函数: 获取所有支持的级别名称
# 返回: 输出所有级别名称(空格分隔)
#-----------------------------------------------------------------------------
function _log_level_get_all() {
    echo "${LOG_LEVEL_NAMES[*]}"
}

#-----------------------------------------------------------------------------
# 测试函数(仅用于模块测试)
#-----------------------------------------------------------------------------
function _log_level_test() {
    echo "=== 日志级别模块测试 ==="
    
    echo "1. 级别转换测试:"
    for level in TRACE DEBUG INFO WARN ERROR FATAL; do
        local num=$(_log_level_to_number "$level")
        local name=$(_log_level_to_name "$num")
        echo "  $level -> $num -> $name"
    done
    
    echo ""
    echo "2. 级别比较测试:"
    _log_should_log "INFO" "DEBUG" && echo "  INFO >= DEBUG: 是" || echo "  INFO >= DEBUG: 否"
    _log_should_log "DEBUG" "INFO" && echo "  DEBUG >= INFO: 是" || echo "  DEBUG >= INFO: 否"
    _log_should_log "ERROR" "ERROR" && echo "  ERROR >= ERROR: 是" || echo "  ERROR >= ERROR: 否"
    
    echo ""
    echo "3. 颜色代码测试:"
    for level in TRACE DEBUG INFO WARN ERROR FATAL; do
        local color=$(_log_level_get_color "$level")
        echo -e "  ${color}${level}${COLOR_RESET}"
    done
    
    echo ""
    echo "4. 有效性验证测试:"
    _log_level_is_valid "INFO" && echo "  INFO: 有效" || echo "  INFO: 无效"
    _log_level_is_valid "INVALID" && echo "  INVALID: 有效" || echo "  INVALID: 无效"
}

# 如果直接执行此脚本,运行测试
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
    _log_level_test
fi

